package logic;

import static java.util.Locale.ENGLISH;
import java.io.File;
import java.util.AbstractMap.SimpleEntry;
import java.util.List;
import java.util.regex.Pattern;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JTextField;
import qw.easyFrame.throwables.DefinedRuntimeException;
import qw.easyFrame.tools.statics.StringUtil;
import qw.easyFrame.view.EasyTextArea;
import view.MainFrame;

/**
 * 控制器.
 * @author Rex
 *
 */
public class Controller {
	
	/**
	 * 标记程序是否正在运行.
	 */
	private static volatile boolean running = false;
	
	/**
	 * 默认需要搜索的文件格式.
	 */
	private static final String[] FORMATS = { ".txt", ".doc", ".docx", ".xls", ".xlsx" };

	public synchronized static void run(File[] chosen, JComboBox<String> box, JTextField target, JTextField formats,
			EasyTextArea area, JCheckBox ignoreCase, JCheckBox fuzzyMatch) {
		if (running) {
			area.append("程序正在运行，请勿重复点击！");
		} else {
			area.append("开始搜索，请稍候……");
			running = true;
			new Thread(() -> act(chosen, box, target, formats, area, ignoreCase, fuzzyMatch)).start();
		}
	}
	
	private static void act(File[] chosen, JComboBox<String> box, JTextField target, JTextField formats,
			EasyTextArea area, JCheckBox ignore, JCheckBox fuzzy) {
		String msg = "搜索已完成！";
		try {
			File file = null;
			if (chosen == null || chosen.length == 0 || (file = chosen[0]) == null) {
				throw new DefinedRuntimeException(false, "您未选择任何文件或文件夹！");
			}
			
			String charset = box.getSelectedItem().toString();
			if (MainFrame.box_text.equals(charset)) {
				charset = null;
			}
			
			String targerText = target.getText().trim();
			if (targerText.isEmpty() || MainFrame.field0_text.equals(targerText)) {
				throw new DefinedRuntimeException(false, "您未输入要搜索的文字！");
			}
			
			String[] format = FORMATS;
			String text = formats.getText().trim();
			if (MainFrame.field1_text.equals(text) == false && text.isEmpty() == false)
				format = StringUtil.split(text, " ");

			// 是否忽略大小写
			Object[] select = ignore.getSelectedObjects();
			boolean ignoreCase = select != null;
			
			// 是否启用星号模糊匹配
			select = fuzzy.getSelectedObjects();
			boolean fuzzyMatch = select != null;
			Pattern pattern = null;
			if (fuzzyMatch)
				pattern = toRegex(targerText, ignoreCase);
			
			TextFinder finder = new TextFinder();
			finder.setDir(file);
			finder.setCharset(charset);
			finder.setExtensions(format);
			if (fuzzyMatch)
				finder.setTarget(pattern, ignoreCase);
			else
				finder.setTarget(targerText, ignoreCase);
			
			List<SimpleEntry<String,Integer>> find = finder.find();
			if (find ==null || find.size()==0)
				throw new DefinedRuntimeException(false, "未搜索到结果！");
			
			for (SimpleEntry<String, Integer> e : find) {
				String fname = e.getKey();
				StringBuilder sb = new StringBuilder(fname);

				int value = e.getValue();
				if (value != -1) {
					sb.append(" 第").append(value);
					if (fname.endsWith(".xls") || fname.endsWith(".xlsx") || fname.endsWith(".pdf")
							|| fname.endsWith(".ppt") || fname.endsWith("pptx"))
						sb.append("页");
					else
						sb.append("段");
				}

				area.append(sb.toString());
			}

		} catch (DefinedRuntimeException e) {
			msg = e.getMessage();
		} catch (Exception e) {
			msg = "程序运行时出现未知的异常！";
		} finally {
			running = false;
			area.append(msg);
		}
	}
	
	/**
	 * 判断是否输入了全部是星号的字符串.
	 */
	private static final Pattern ERR = Pattern.compile("^[*]+$");
	
	/**
	 * 将关键词转换为正则表达式.
	 * @param targerText
	 * @param ignoreCase 
	 * @return
	 */
	private static final Pattern toRegex(String targerText, boolean ignoreCase) {
		if (ERR.matcher(targerText).matches()) {
			throw new DefinedRuntimeException(false, "禁止仅输入星号！");
		} else {
			if (ignoreCase)
				targerText = targerText.toLowerCase(ENGLISH);
			
			targerText = targerText.replace("*", "(.){0,1}");
			targerText = "(.)*" + targerText + "(.)*";
		}
		return Pattern.compile(targerText);
	}
	
}